In this analysis we will look at how MRR has grown in 2017. We will look at the overall growth of MRR as measured by our daily MRR calculation, and we will look at the MRR components (new, churn, etc.) as measured by the Stripe MRR breakdown script.
We will try to determine if there are any long term trends in the MRR we gain and lose each week to determine if net mrr, defined as MRR gained less MRR lost in any given time period, is trending towards 0.
We will also run simulations based on historical MRR growth to predict what the MRR growth rate will be given certain conditions.
We will aggregate MRR growth, and the growth of the components that make up MRR, by week. I chose this because it is a standard unit of time. It will help us compare time windows of the same length, which we cannot do with months. Months also have differing numbers of weekdays in them, which impacts MRR growth.
Let’s start by looking at how Stripe MRR has grown each week this year, as measured by the daily MRR calculation.
The data suggests that 2016 was a bit more volatile than 2017 has been so far. We experimented with trial length and pricing, which caused some volatility. Overall the amount of MRR growth from Stripe each week seems relatively stable. There may be a slight negative trend over the past several weeks however.
Let’s look at the MRR breakdown data.
Now we can look at the weekly MRR amounts that were gained and lost in the past 8 months. These amounts were calculated with the new Stripe MRR breakdown script.
It looks like there may be an issue with the data on the last week of June, let’s remove it. We can stil learn from this data. Let’s add new and upgrade together to get net gained, and churn and downgrade to get net lost.
We can flip the sign on net lost to get a better comparison.
We can see in this graph that net_lost has increased over time, but so has net_gained. There is always a gap between the two, but it isn’t easy to tell if the gap is growing, shrinking, or staying about the same. We can find out by looking at the overall net MRR amount, which is equal to new + upgrade - churn - downgrade MRR.
There is a lot of variance, so we can try to fit a smoother over this data to view longer term trands. Remember that something could be off with the data from the last week of June.
In the past 8 months, the data suggests that there may have been a slight decrease in MRR gained after the end of April, but it doesn’t seem like the trend continues to decrease after that.
I suspect that there is a seasonal component that affects this data, but I haven’t yet had time to backfill data through 2016 and 2015, so we may have to wait to confirm that.
We can go through the exercise of thinking about the worst-case scenario. In the very first graph of this analysis, in which I show the amount that Stripe MRR has changed each week in the past two years, we can fit a straight line through the data.
# get linear equation
lm_mod <- lm(change ~ week, data = mrr)
summary(lm_mod)
##
## Call:
## lm(formula = change ~ week, data = mrr)
##
## Residuals:
## Min 1Q Median 3Q Max
## -4976.2 -1414.4 -143.1 1400.1 4513.9
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 25821.006 19275.560 1.340 0.184
## week -1.151 1.126 -1.022 0.310
##
## Residual standard error: 1815 on 84 degrees of freedom
## (1 observation deleted due to missingness)
## Multiple R-squared: 0.01228, Adjusted R-squared: 0.0005187
## F-statistic: 1.044 on 1 and 84 DF, p-value: 0.3098
The formula for this line is change = beta + (-1.151 * week), which means that MRR change decreases by 1-2 dollars each week. It would take thousands of weeks for this straight line to hit 0.
It’s worth noting that the effect of week on MRR change is not significant, meaning that there is not a significant negative effect on MRR, according to this linear regression model.
Instead of this approach, we can use the variance in MRR change to simulate how the future could play out in thousands of parrallel universes. We can generate a random MRR growth number that is based on the average MRR growth in the past two years and the variance in that number. We can repeat that proccess thousands of times to give us an idea of how things could play out, and can then take the average to find how things are more likely to turn out.
# find mean mrr growth
mean(mrr$change, na.rm = TRUE)
## [1] 6125.872
# get the standard deviation
sd(mrr$change, na.rm = TRUE)
## [1] 1815.237
We can now generate random samples from the distribution of MRR change. Here are 10 of such numbers.
# generate random sample of 10 months of mrr growth.
rnorm(10, mean = mean(mrr$change, na.rm = T), sd = sd(mrr$change, na.rm = T))
## [1] 7958.136 6700.528 6094.385 6958.571 6842.807 6440.073 5644.590
## [8] 6273.746 4592.018 6783.203
Now let’s get a sample of 52, simulating MRR growth for the next year, and repeat this 100 times.
Each line represents a different simulation based on our historical data. This is what would happen if we plotted the average of all 100 simulations for each week.
ggplot() +
geom_line(aes(x = week, y = samp, color = run), alpha = 0.2, data = runs) +
geom_line(aes(x = week, y = mean_samp), data = by_week) +
guides(color = FALSE) +
theme_minimal() +
labs(x = NULL, y = NULL, title = "Weekly MRR Change Simulations")
The first plot looked to be trending downwards to me, but the average is linear.